package fr.webeo.teambuilder.ao;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import fr.webeo.teambuilder.bo.Player;
import fr.webeo.teambuilder.bo.Team;

/**
 * The class <strong>FootModel</strong>.
 * 
 * @author Sébastien Bordes
 * @version $Revision$ $Date$ $Name$
 * 
 * @since fr.webeo.teambuilder 1.0
 */
public class FootModel extends AbstractModel implements TableModelListener {

    /** . */
    @SuppressWarnings("boxing")
    private static final Integer[] COMBO_VALUES = new Integer[] { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
    /** . */
    private MyTableModel tableModel;

    /** . */
    boolean mode;

    /** . */
    private Document doc;

    /** . */
    private Element root;

    /** . */
    private URL codeBase;

    private boolean suspensMode = false;

    /** . */
    private TeamForNPlayerModel teamForNPlayerModel;

    /** . */
    private PlayerForNTeamModel playerForNTeamModel;

    /**
     * @param mode
     */
    public FootModel(boolean mode) {
        tableModel = null;
        setMode(mode);
        setPlayerForNTeamModel(new PlayerForNTeamModel());
        setTeamForNPlayerModel(new TeamForNPlayerModel());
    }

    /**
     * @return
     */
    public MyTableModel getTableModel() {
        if (tableModel == null) {
            tableModel = new MyTableModel(getPlayerList());
            tableModel.addTableModelListener(this);
        }
        return tableModel;
    }

    /**
     * @return
     */
    public List<Player> getPlayerList() {
        try {
            SAXBuilder sxb = new SAXBuilder();
            if (isMode()) {
                doc = sxb.build(new File("players.xml"));
            } else {
                System.err.println(getCodeBase());
                doc = sxb.build(new DataInputStream((new URL(getCodeBase(), "players.xml")).openStream()));
            }
            List<Player> listing = new ArrayList<Player>();
            if (doc != null) {
                setRoot(doc.getRootElement());
                List<Element> l = getRoot().getChildren("player");
                for (int i = 0; i < l.size(); i++) {
                    Element e = l.get(i);
                    listing.add(new Player(e));
                }

                return listing;
            }
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @return
     */
    private URL getCodeBase() {
        return codeBase;
    }

    /**
     * @return
     */
    public List<Player> getReadyPlayers() {
        List<Player> v = new ArrayList<Player>();
        for (int i = 0; i < getTableModel().getRowCount(); i++) {
            if (((Boolean) getTableModel().getValueAt(i, 0)).booleanValue()) {
                v.add(getTableModel().getValueAt(i));
            }
        }
        return v;
    }

    /**
     * 
     */
    public void save() {
        XMLOutputter sortie = new XMLOutputter(Format.getPrettyFormat());
        try {
            sortie.output(doc, new FileOutputStream(new File("players.xml")));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @return
     */
    public Element getRoot() {
        return root;
    }

    /**
     * @param root
     */
    public void setRoot(Element root) {
        this.root = root;
    }

    /**
     * 
     */
    public void tableChanged(TableModelEvent e) {

        // Insert is an update ;)
        // Update
        if (e.getType() == 0 && getTableModel().getValueAt(e.getFirstRow()).isValid()) {
            if (getRoot().indexOf(getTableModel().getValueAt(e.getFirstRow()).getElement()) == -1) {
                getRoot().addContent(getTableModel().getValueAt(e.getFirstRow()).getElement());
                getTableModel().addEmptyLine();
            }
            save();
        }

        // Delete
        if (e.getType() == -1)
            save();
    }

    /**
     * @param selectedRow
     */
    public void delete(int selectedRow) {
        if (getRoot().removeContent(getTableModel().getValueAt(selectedRow).getElement()))
            getTableModel().delete(selectedRow);
    }

    /**
     * @return
     */
    public boolean isMode() {
        return mode;
    }

    /**
     * @param mode
     */
    public void setMode(boolean mode) {
        this.mode = mode;
    }

    /**
     * @param codeBase
     */
    public void setCodeBase(URL codeBase) {
        this.codeBase = codeBase;
    }

    /**
     * @param teams The teams to set.
     */
    @Override
    public void setTeams(List<Team> teams) {
        super.setTeams(teams);
        getTeamForNPlayerModel().setTeams(getTeams());
        getPlayerForNTeamModel().setTeams(getTeams());
    }

    /**
     * @param b
     */
    public void setSuspensMode(boolean b) {
        this.suspensMode = b;
    }

    /**
     * @return Returns the suspensMode.
     */
    public boolean isSuspensMode() {
        return this.suspensMode;
    }

    /**
     * @return Returns the playerForNTeamModel.
     */
    public PlayerForNTeamModel getPlayerForNTeamModel() {
        return this.playerForNTeamModel;
    }

    /**
     * @param playerForNTeamModel The playerForNTeamModel to set.
     */
    public void setPlayerForNTeamModel(PlayerForNTeamModel playerForNTeamModel) {
        this.playerForNTeamModel = playerForNTeamModel;
    }

    /**
     * @return Returns the teamForNPlayerModel.
     */
    public TeamForNPlayerModel getTeamForNPlayerModel() {
        return this.teamForNPlayerModel;
    }

    /**
     * @param teamForNPlayerModel The teamForNPlayerModel to set.
     */
    public void setTeamForNPlayerModel(TeamForNPlayerModel teamForNPlayerModel) {
        this.teamForNPlayerModel = teamForNPlayerModel;
    }

    public ComboBoxModel getComboBoxModel() {
        DefaultComboBoxModel dcm = new DefaultComboBoxModel(COMBO_VALUES);
        return dcm;
    }

}
